package typeErasure;

public class GenericFruit { // top level class


    // 在类中定义使用泛型的静态方法，需要额外添加泛型声明（将这个方法定义为泛型方法）
//       public static void show(T t) {
//
//       }

    public static <T> void show(T t) {

    }


    class Fruit { // nested class

        @Override
        public String toString() {
            return "fruit";
        }

    }


    class Apple extends Fruit {
        @Override
        public String toString() {
            return "Apple";
        }
    }

    static class AppleStatic {
        @Override
        public String toString() {
            return "appleStatic";
        }
    }

    class Person {
        @Override
        public String toString() {
            return "Person";
        }
    }

    class GenerateTest<T> {

        public void show_1(T t) {
            System.out.println(t.toString());
        }

        /**
         * 在泛型类中声明一个泛型方法，使用泛型E，这种泛型可以为任意类型， 也可以与T相同
         * 由于泛型方法在声明的时候会声明泛型<E>, 因此在泛型类中并未声明泛型，编译器也能够正确识别泛型方法中识别的泛型
         *
         * @param t
         * @param <E>
         */
        public <E> void show_3(E t) {
            System.out.println(t.toString());
        }


        /**
         * 在泛型类中声明一份泛型方法，使用泛型T，这个T是一种全新的类型，可以与泛型类中声明的T不是同一种类型
         *
         * @param t
         * @param <T>
         */
        public <T> void show_2(T t) {
            System.out.println(t.toString());
        }

        // 方法泛型 可变参数
        public <T> void printMsg(T... args) {
            for (T t : args) {
                System.out.println("generic test:" + t);
            }
        }
    }


    public class StaticGenerator<T> {


    }


    public static void main(String[] args) {

        // 实例化静态内部类
//        AppleStatic appleStatic = new AppleStatic();
//        System.out.println(appleStatic);


        // 实例化非静态内部类1
        GenericFruit genericFruit = new GenericFruit();
        GenericFruit.Apple apple = genericFruit.new Apple();

        new GenericFruit().test();
    }


    private void test() {
        Apple apple = new Apple();
        Person person = new Person();

        GenerateTest<Fruit> generateTest = new GenerateTest<>();
        generateTest.show_1(apple);

        // 编译错误， 因为泛型实参给的Fruit， 传入的则是Person
//        generateTest.show_1(person);

        // 两个方法都可以成功
        generateTest.show_2(apple);
        generateTest.show_2(person);

        // 成功
        generateTest.show_3(apple);
        generateTest.show_3(person);


        generateTest.printMsg("111", 111, 232.4, 55.55);


    }

}
